package com.yunhe.policyfulfillment.authority.service.impl;

import com.alibaba.fastjson.support.odps.udf.CodecCheck;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.model.mybatis.PageResult;
import com.yunhe.common.util.CollectionUtil;
import com.yunhe.policyfulfillment.authority.domain.PolicyRole;
import com.yunhe.policyfulfillment.authority.domain.PolicyRoleAndMenuRelation;
import com.yunhe.policyfulfillment.authority.domain.PolicyUser;
import com.yunhe.policyfulfillment.authority.model.PolicyRoleQueryCondition;
import com.yunhe.policyfulfillment.authority.repository.PolicyRoleRepository;
import com.yunhe.policyfulfillment.authority.service.IPolicyUserService;
import com.yunhe.policyfulfillment.authority.service.PolicyRoleAndMenuRelationService;
import com.yunhe.policyfulfillment.authority.service.PolicyRoleService;
import com.yunhe.policyfulfillment.constant.PolicyFulfillmentConstant;
import com.yunhe.policyfulfillment.util.MyHeaderUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author zhengbo
 * @date 2021/9/17 17:21
 */
@Service
@Slf4j
public class PolicyRoleServiceImpl implements PolicyRoleService {

    @Autowired
    private PolicyRoleRepository policyRoleRepository;

    @Autowired
    private MyHeaderUtil headerUtil;

    @Autowired
    private IPolicyUserService iPolicyUserService;

    @Autowired
    private PolicyRoleAndMenuRelationService policyRoleAndMenuRelationService;

    @Override
    public int createPolicyRoleSelective(PolicyRole policyRole) throws ArgumentErrorException {
        if (StringUtils.isEmpty(policyRole.getTitle())) {
            throw new ArgumentErrorException("角色名不能为空");
        }
        PolicyRole existPolicyRole = policyRoleRepository.searchPolicyRoleByRoleTitle(policyRole.getTitle());
        if (existPolicyRole != null) {
            throw new ArgumentErrorException("该角色名已存在");
        }
        PolicyUser user = headerUtil.getHeaderUser();
        if (user != null) {
            policyRole.setCreator(user.getUserName());
        }
        policyRole.setSn(String.valueOf(System.currentTimeMillis()));
        return policyRoleRepository.createPolicyRoleSelective(policyRole);
    }

    @Override
    public int deletePolicyRoleByPrimaryKey(Long id) throws ArgumentErrorException {
        //如果角色绑定了用户，则提示不可删除
        List<PolicyUser> policyUsers = iPolicyUserService.findPolicyUsersByRoleId(id);
        if (CollectionUtil.isNotEmpty(policyUsers)) {
            throw new ArgumentErrorException("该角色已绑定用户，请先解绑再删除");
        }
        //同步删除关系表
        policyRoleAndMenuRelationService.deletePolicyMenusByRoleId(id);
        return policyRoleRepository.deletePolicyRoleByPrimaryKey(id);
    }

    @Override
    public void deletePolicyRoleByIds(String ids) throws ArgumentErrorException {
        String[] idsStr = ids.split(",");
        for (String id : idsStr) {
            PolicyRole policyRole = policyRoleRepository.searchPolicyRoleByPrimaryKey(Long.valueOf(id));
            if(PolicyFulfillmentConstant.Role_Name.Admin.value().equals(policyRole.getRoleCode())){
                throw new ArgumentErrorException("管理员角色不能删除！");
            }
            if(policyRole.isInitRole()){
                throw new ArgumentErrorException("初始化角色不能删除");
            }
            deletePolicyRoleByPrimaryKey(Long.valueOf(id));
        }
    }

    @Override
    public int updatePolicyRoleByPrimaryKeySelective(PolicyRole policyRole) throws ArgumentErrorException {
        if (StringUtils.isEmpty(policyRole.getTitle())) {
            throw new ArgumentErrorException("角色名不能为空");
        }
        PolicyRole existPolicyRole = policyRoleRepository.searchPolicyRoleByRoleTitle(policyRole.getTitle());
        if (existPolicyRole != null && !existPolicyRole.getId().equals(policyRole.getId())) {
            throw new ArgumentErrorException("该角色名已存在");
        }
        return policyRoleRepository.updatePolicyRoleByPrimaryKeySelective(policyRole);
    }

    @Override
    public PolicyRole searchPolicyRoleByPrimaryKey(Long id) {
        return policyRoleRepository.searchPolicyRoleByPrimaryKey(id);
    }

    @Override
    public List<PolicyRole> searchPolicyRoleList(PolicyRoleQueryCondition policyRoleQueryCondition) {
        List<PolicyRole> policyRoleList = policyRoleRepository.searchPolicyRoleList(policyRoleQueryCondition);
        policyRoleList.forEach(policyRole -> {
            List<PolicyUser> users = iPolicyUserService.findPolicyUsersByRoleId(policyRole.getId());
            policyRole.setNumberOfAssociatedUsers((long) users.size());
        });
        //policyRoleList.removeIf(policyRole -> "Admin".equals(policyRole.getRoleCode()));
        return policyRoleList;
    }

    @Override
    public PageResult<PolicyRole> searchPolicyRoleForPage(PolicyRoleQueryCondition policyRoleQueryCondition) {
        PageMethod.startPage(policyRoleQueryCondition.getPage(), policyRoleQueryCondition.getSize());
        List<PolicyRole> policyRoleList = searchPolicyRoleList(policyRoleQueryCondition);
        PageInfo<PolicyRole> pageInfo = new PageInfo<>(policyRoleList);
        return new PageResult<>(policyRoleQueryCondition.getPage(), policyRoleQueryCondition.getSize(),
                (int) pageInfo.getTotal(), policyRoleList);
    }

    @Override
    public void roleBindOrUnbindMenu(Long roleId, String menuIds) {
        PolicyUser user = headerUtil.getHeaderUser();
        String creator = "";
        if (user != null) {
            creator = user.getUserName();
        }

        //先解绑再绑定
        policyRoleAndMenuRelationService.deletePolicyMenusByRoleId(roleId);
        if (StringUtils.isNotEmpty(menuIds)) {
            String[] menuIdsStr = menuIds.split(",");
            for (String id : menuIdsStr) {
                PolicyRoleAndMenuRelation policyRoleAndMenuRelation = new PolicyRoleAndMenuRelation();
                policyRoleAndMenuRelation.setMenuId(Long.valueOf(id));
                policyRoleAndMenuRelation.setRoleId(roleId);
                policyRoleAndMenuRelation.setCreator(creator);
                policyRoleAndMenuRelationService.createPolicyRoleAndMenuRelationSelective(policyRoleAndMenuRelation);
            }
        }
    }
}
